package handler

import (
	"net/http"
	"net/url"
	"strings"
	"time"

	"go-file-perception-model/internal/logger"
	"go-file-perception-model/internal/model"
	"go-file-perception-model/internal/service"
	"go.uber.org/zap"

	"github.com/gin-gonic/gin"
)

// SearchHandler 搜索处理器
type SearchHandler struct {
	fileService *service.FileService
}

// NewSearchHandler 创建搜索处理器实例
func NewSearchHandler(fileService *service.FileService) *SearchHandler {
	return &SearchHandler{
		fileService: fileService,
	}
}

// SemanticSearch 处理语义搜索请求
func (h *SearchHandler) SemanticSearch(c *gin.Context) {
	var req model.SemanticSearchRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"success": false,
			"message": "Invalid request format",
			"error":   err.Error(),
		})
		return
	}

	// 验证请求参数
	if req.Query == "" {
		c.JSON(http.StatusBadRequest, gin.H{
			"success": false,
			"message": "Query cannot be empty",
		})
		return
	}

	// 设置默认值
	if req.Limit <= 0 {
		req.Limit = 10
	}
	if req.TopK <= 0 {
		req.TopK = req.Limit
	}
	if req.DedupMultiplier <= 0 {
		req.DedupMultiplier = 100
	}

	// 记录搜索开始时间和原始结果数量
	startTime := time.Now()
	var originalCount int

	// 调用服务层处理语义搜索
	results, err := h.fileService.SemanticSearch(req)
	if err != nil {
		logger.Error("Failed to perform semantic search", zap.Error(err))
		c.JSON(http.StatusInternalServerError, gin.H{
			"success": false,
			"message": "Failed to perform semantic search",
			"error":   err.Error(),
		})
		return
	}

	// 如果启用去重，记录原始结果数量
	if req.EnableDedup {
		// 这里我们无法直接获取原始结果数量，因为去重逻辑在服务层
		// 我们可以通过估算来设置一个合理的值
		originalCount = req.Limit * req.DedupMultiplier
		if originalCount > 1000 {
			originalCount = 1000
		}
	}

	// 计算搜索耗时
	took := time.Since(startTime).Milliseconds()

	c.JSON(http.StatusOK, gin.H{
		"success": true,
		"message": "Semantic search completed successfully",
		"data": model.SearchResponse{
			Results:       results,
			Total:         len(results),
			Query:         req.Query,
			SearchType:    "semantic",
			Took:          took,
			EnableDedup:   req.EnableDedup,
			OriginalCount: originalCount,
		},
	})
}

// RegexSearch 处理正则表达式搜索请求
func (h *SearchHandler) RegexSearch(c *gin.Context) {
	var req model.RegexSearchRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"success": false,
			"message": "Invalid request format",
			"error":   err.Error(),
		})
		return
	}

	// 验证请求参数
	if req.Pattern == "" {
		c.JSON(http.StatusBadRequest, gin.H{
			"success": false,
			"message": "Pattern cannot be empty",
		})
		return
	}

	// 添加调试日志
	logger.Info("Regex pattern received", zap.String("original_pattern", req.Pattern))
	
	// 检查pattern是否被URL编码
	// 如果pattern中包含%字符，说明可能是URL编码的
	if strings.Contains(req.Pattern, "%") {
		// 对URL编码的pattern进行解码
		decodedPattern, err := url.QueryUnescape(req.Pattern)
		if err != nil {
			c.JSON(http.StatusBadRequest, gin.H{
				"success": false,
				"message": "Failed to decode pattern",
				"error":   err.Error(),
			})
			return
		}
		
		// 添加调试日志
		logger.Info("Regex pattern after URL decoding", zap.String("decoded_pattern", decodedPattern))
		
		// 使用解码后的模式
		req.Pattern = decodedPattern
	}
	
	// 添加调试日志
	logger.Info("Regex pattern final", zap.String("final_pattern", req.Pattern))

	// 设置默认值
	if req.Limit <= 0 {
		req.Limit = 10
	}
	if req.DedupMultiplier <= 0 {
		req.DedupMultiplier = 100
	}

	// 记录搜索开始时间和原始结果数量
	startTime := time.Now()
	var originalCount int

	// 调用服务层处理正则表达式搜索
	results, err := h.fileService.RegexSearch(req)
	if err != nil {
		logger.Error("Failed to perform regex search", zap.Error(err))
		c.JSON(http.StatusInternalServerError, gin.H{
			"success": false,
			"message": "Failed to perform regex search",
			"error":   err.Error(),
		})
		return
	}

	// 如果启用去重，记录原始结果数量
	if req.EnableDedup {
		// 这里我们无法直接获取原始结果数量，因为去重逻辑在服务层
		// 我们可以通过估算来设置一个合理的值
		originalCount = req.Limit * req.DedupMultiplier
		if originalCount > 1000 {
			originalCount = 1000
		}
	}

	// 计算搜索耗时
	took := time.Since(startTime).Milliseconds()

	c.JSON(http.StatusOK, gin.H{
		"success": true,
		"message": "Regex search completed successfully",
		"data": model.SearchResponse{
			Results:       results,
			Total:         len(results),
			Query:         req.Pattern,
			SearchType:    "regex",
			Took:          took,
			EnableDedup:   req.EnableDedup,
			OriginalCount: originalCount,
		},
	})
}